package com.xyy.saas.payment.payment.core.service;

import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.dao.model.PayResultOrder;
import com.xyy.saas.payment.dao.model.PrePayOrder;
import com.xyy.saas.payment.payment.core.dto.ChannelAndOrderNoDto;
import com.xyy.saas.payment.service.PayResultOrderService;
import com.xyy.saas.payment.util.ApolloUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class PayOrderService {
    @Resource
    private PrePayOrderService prePayOrderService;
    @Resource
    private PayResultOrderService payResultOrderService;

    /**
     * 根据业务支付单号查询支付渠道
     * @param businessOrderNo
     * @param amount
     * @return
     */
    public ChannelAndOrderNoDto getPayChannelAndOrderNo(String businessOrderType, String businessOrderNo,
                                                        Integer amount, String thirdType) throws PaymentException
    {
        if(StringUtils.isBlank(businessOrderNo)) {
            throw new PaymentException(ResultCodeEnum.PARAM_SUBJECT_ERROR);
        }

        List<PrePayOrder> prePayOrders = prePayOrderService.likePrePayOrderByBusinessOrderNo(businessOrderType, businessOrderNo);

        if(CollectionUtils.isEmpty(prePayOrders)) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(), "Not fount PrePayOrder by businessOrderNo=" + businessOrderNo);
        }

        String payChannel = null;
        String payNo = null;
        Date payDate = null;

        for(PrePayOrder prePayOrder : prePayOrders) {
            List<PayResultOrder> payResultOrders = payResultOrderService.selectListByPayNo(prePayOrder.getPayNo());

            if(CollectionUtils.isEmpty(payResultOrders)) {
                continue;
            }

            for(PayResultOrder payResultOrder : payResultOrders) {
                if(amount != null && !amount.equals(payResultOrder.getAmount())) {
                    throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(), "Detail pay amount not match, businessOrderNo=" + businessOrderNo);
                }

                if(StringUtils.isBlank(payChannel)) {
                    payChannel = getPayChannel0(payResultOrder.getPayChannel(), payResultOrder.getMerchantId(), thirdType);
                    payNo = payResultOrder.getPayNo();
                    payDate = payResultOrder.getCtime();
                }
                else {
                    // 同一订单重复支付，取富民渠道或平安渠道
                    boolean isLatestPayDate = payDate != null && payResultOrder.getCtime().compareTo(payDate) > 0;
                    boolean payChannelCondition = Constants.thirdChannelSubmitPingan(payChannel) || payChannel.contains(Constants.CHANNEL_FUMIN_BANK_NAME) || payChannel.contains(Constants.CHANNEL_PINGAN_NAME);
                    if (payChannelCondition && isLatestPayDate) {
                        // do nothing
                    }
                    else {
                        payChannel = getPayChannel0(payResultOrder.getPayChannel(), payResultOrder.getMerchantId(), thirdType);
                        payNo = payResultOrder.getPayNo();
                        payDate = payResultOrder.getCtime();
                    }
                }
            }
        }

        if(StringUtils.isBlank(payChannel) || StringUtils.isBlank(payNo) || payDate == null) {
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(), "Not fount PayResultOrder by businessOrderNo=" + businessOrderNo);
        }

        return ChannelAndOrderNoDto.builder().channel(payChannel).orderNo(payNo).tradeDate(payDate).build();
    }

    /**
     * 适配支付渠道，富民轮训户走直连渠道结算
     * https://wiki.int.ybm100.com/pages/viewpage.action?pageId=438594041
     * @param payChannel
     * @param merchantId
     * @return
     */
    private String getPayChannel0(String payChannel, String merchantId, String thirdType) {
        if(StringUtils.isBlank(merchantId) || !Constants.QIFUTONG.equals(thirdType)) {
            return payChannel;
        }
        if(ApolloUtil.getProperty(Constants.FBANK_YBM_TECH_ACCOUNT_NO, StringUtils.EMPTY).contains(merchantId))  {
            return Constants.CHANNEL_DIRECT_NAME + payChannel.substring(payChannel.indexOf(Constants.UNDER_LINE));
        }
        return payChannel;
    }

}
